// XByte.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"

#include <XByteMain.h>
#include <XKey.h>

#include <DevIL\il.h>
#include <fstream>
#include <cstdlib>
#include <Windows.h>

XByteMain* XByteMain::Instance;

XByteMain::XByteMain()
{
	Instance = this;
}

XByteMain::~XByteMain()
{
	delete Instance;
}

void XByteMain::_close()
{
	Instance->UnloadContent();
}

void XByteMain::_loadConfig(const char* path)
{
	XInitializationFile newFile;
	newFile.LoadFile(path, 200);
	ScreenWidth = newFile.GetInt("ScreenWidth");
	ScreenHeight = newFile.GetInt("ScreenHeight");
	Title = newFile.GetString("Title");
	Fps = newFile.GetInt("Fps");

	if(newFile.GetString("Fullscreen") == "true")
		Fullscreen = true;
	else
		Fullscreen = false;

}

void XByteMain::_update(int val)
{
	Instance->Mouse.WheelDown.SetReleased();
	Instance->Mouse.WheelUp.SetReleased();

	Instance->Update();
	_render();

	Instance->Mouse.Update();
	for(int i=0; i<149; i++)
		Instance->Button[i].Update();

	glutTimerFunc(100/Instance->Fps, _update, val);
}

void XByteMain::_render()
{
	glClear(GL_COLOR_BUFFER_BIT);
	glPushMatrix();
	Instance->Draw();
	glPopMatrix();
	glutSwapBuffers();
}

void XByteMain::_keyboard(unsigned char key, int x, int y)
{
	Instance->Button[key].SetPressed();
	Instance->Mouse.SetPosition(x, y);

}

void XByteMain::_keyboardUp(unsigned char key, int x, int y)
{
	Instance->Button[key].SetReleased();

	if(key >97 && key < 122)
		Instance->Button[key+32].SetReleased();

	Instance->Mouse.SetPosition(x, y);
}

void XByteMain::_special(int key, int x, int y)
{
	Instance->Mouse.SetPosition(x, y);

	switch(key)
	{
	case GLUT_KEY_F1:
		Instance->Button[XKEY_F1].SetPressed();
		break;

	case GLUT_KEY_F2:
		Instance->Button[XKEY_F2].SetPressed();
		break;

	case GLUT_KEY_F3:
		Instance->Button[XKEY_F3].SetPressed();
		break;

	case GLUT_KEY_F4:
		Instance->Button[XKEY_F4].SetPressed();
		break;

	case GLUT_KEY_F5:
		Instance->Button[XKEY_F5].SetPressed();
		break;

	case GLUT_KEY_F6:
		Instance->Button[XKEY_F6].SetPressed();
		break;

	case GLUT_KEY_F7:
		Instance->Button[XKEY_F7].SetPressed();
		break;

	case GLUT_KEY_F8:
		Instance->Button[XKEY_F8].SetPressed();
		break;

	case GLUT_KEY_F9:
		Instance->Button[XKEY_F9].SetPressed();
		break;

	case GLUT_KEY_F10:
		Instance->Button[XKEY_F10].SetPressed();
		break;

	case GLUT_KEY_F11:
		Instance->Button[XKEY_F11].SetPressed();
		break;

	case GLUT_KEY_F12:
		Instance->Button[XKEY_F12].SetPressed();
		break;

	case GLUT_KEY_LEFT:
		Instance->Button[XKEY_LEFT].SetPressed();
		break;

	case GLUT_KEY_UP:
		Instance->Button[XKEY_UP].SetPressed();
		break;

	case GLUT_KEY_RIGHT:
		Instance->Button[XKEY_RIGHT].SetPressed();
		break;

	case GLUT_KEY_DOWN:
		Instance->Button[XKEY_DOWN].SetPressed();
		break;

	case GLUT_KEY_PAGE_UP:
		Instance->Button[XKEY_PAGE_UP].SetPressed();
		break;

	case GLUT_KEY_PAGE_DOWN:
		Instance->Button[XKEY_PAGE_DOWN].SetPressed();
		break;

	case GLUT_KEY_HOME:
		Instance->Button[XKEY_HOME].SetPressed();
		break;

	case GLUT_KEY_END:
		Instance->Button[XKEY_END].SetPressed();
		break;

	case GLUT_KEY_INSERT:
		Instance->Button[XKEY_INSERT].SetPressed();
		break;
	}
}

void XByteMain::_specialUp(int key, int x, int y)
{
	Instance->Mouse.SetPosition(x, y);

	switch(key)
	{
	case GLUT_KEY_F1:
		Instance->Button[XKEY_F1].SetReleased();
		break;

	case GLUT_KEY_F2:
		Instance->Button[XKEY_F2].SetReleased();
		break;

	case GLUT_KEY_F3:
		Instance->Button[XKEY_F3].SetReleased();
		break;

	case GLUT_KEY_F4:
		Instance->Button[XKEY_F4].SetReleased();
		break;

	case GLUT_KEY_F5:
		Instance->Button[XKEY_F5].SetReleased();
		break;

	case GLUT_KEY_F6:
		Instance->Button[XKEY_F6].SetReleased();
		break;

	case GLUT_KEY_F7:
		Instance->Button[XKEY_F7].SetReleased();
		break;

	case GLUT_KEY_F8:
		Instance->Button[XKEY_F8].SetReleased();
		break;

	case GLUT_KEY_F9:
		Instance->Button[XKEY_F9].SetReleased();
		break;

	case GLUT_KEY_F10:
		Instance->Button[XKEY_F10].SetReleased();
		break;

	case GLUT_KEY_F11:
		Instance->Button[XKEY_F11].SetReleased();
		break;

	case GLUT_KEY_F12:
		Instance->Button[XKEY_F12].SetReleased();
		break;

	case GLUT_KEY_LEFT:
		Instance->Button[XKEY_LEFT].SetReleased();
		break;

	case GLUT_KEY_UP:
		Instance->Button[XKEY_UP].SetReleased();
		break;

	case GLUT_KEY_RIGHT:
		Instance->Button[XKEY_RIGHT].SetReleased();
		break;

	case GLUT_KEY_DOWN:
		Instance->Button[XKEY_DOWN].SetReleased();
		break;

	case GLUT_KEY_PAGE_UP:
		Instance->Button[XKEY_PAGE_UP].SetReleased();
		break;

	case GLUT_KEY_PAGE_DOWN:
		Instance->Button[XKEY_PAGE_DOWN].SetReleased();
		break;

	case GLUT_KEY_HOME:
		Instance->Button[XKEY_HOME].SetReleased();
		break;

	case GLUT_KEY_END:
		Instance->Button[XKEY_END].SetReleased();
		break;

	case GLUT_KEY_INSERT:
		Instance->Button[XKEY_INSERT].SetReleased();
		break;
	}
}

void XByteMain::_mouseWheel(int button, int direction, int x, int y)
{
	Instance->Mouse.SetPosition(x, y);

	if (direction > 0)
	{
		Instance->Mouse.WheelUp.SetPressed();
		Instance->Mouse.WheelDown.SetReleased();
	}
    else if(direction < 0)
	{
		Instance->Mouse.WheelUp.SetReleased();
		Instance->Mouse.WheelDown.SetPressed();
	}
	else
	{
		Instance->Mouse.WheelDown.SetReleased();
		Instance->Mouse.WheelUp.SetReleased();
	}
}

void XByteMain::_mouse(int button, int state, int x, int y)
{
	Instance->Mouse.SetPosition(x, y);

	if(state == GLUT_DOWN)
	{
		if(button == GLUT_LEFT_BUTTON)
			Instance->Mouse.LeftButton.SetPressed();
		
		else if (button == GLUT_MIDDLE_BUTTON)
			Instance->Mouse.MiddleButton.SetPressed();
		
		else if (button == GLUT_RIGHT_BUTTON)
			Instance->Mouse.RightButton.SetPressed();
	}
	else if(state == GLUT_UP)
	{
		if(button == GLUT_LEFT_BUTTON)
			Instance->Mouse.LeftButton.SetReleased();

		else if (button == GLUT_MIDDLE_BUTTON)
			Instance->Mouse.MiddleButton.SetReleased();
		
		else if (button == GLUT_RIGHT_BUTTON)
			Instance->Mouse.RightButton.SetReleased();
	}
}

void XByteMain::_motion(int x, int y)
{
	Instance->Mouse.SetPosition(x, y);
}

void XByteMain::Initialize(int& argc, char* args[])
{
	_loadConfig("XByte.ini");

	glutInit(&argc, args);
	glutInitContextVersion(2, 1);
	glutInitDisplayMode(GLUT_DOUBLE);
	glutInitWindowSize(ScreenWidth, ScreenHeight);
	glutCreateWindow(Title.c_str());
	if(Fullscreen)
		glutFullScreen();

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	if(Fullscreen)
		glOrtho(0, glutGet(GLUT_SCREEN_WIDTH), glutGet(GLUT_SCREEN_HEIGHT), 0, 1, -1);
	else
		glOrtho(0, ScreenWidth, ScreenHeight, 0, 1, -1);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	glEnable(GL_TEXTURE_2D);
	glEnable(GL_BLEND);
	glDisable(GL_DEPTH_TEST);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	glClearColor(0, 0, 0, 1);

	ilInit();
	ilClearColor(255, 255, 255, 0);

	glewInit();

	glutDisplayFunc(_render);
	glutKeyboardFunc(_keyboard);
	glutKeyboardUpFunc(_keyboardUp);
	glutSpecialFunc(_special);
	glutSpecialUpFunc(_specialUp);
	glutMouseWheelFunc(_mouseWheel);
	glutMouseFunc(_mouse);
	glutPassiveMotionFunc(_motion);
	glutMotionFunc(_motion);
	glutTimerFunc(100/Fps, _update, 0);
	glutCloseFunc(_close);

	LoadContent();

	
	glutMainLoop();
}

void XByteMain::Exit()
{
	glutLeaveMainLoop();
}


